﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class VoiceRecordAccumulate : MonoBehaviour
{
#if UNITY_WEBGL
#else
    public AudioClip clip;
    public int samplingRate = 8000;
    public float length;

    public int maxRecordTime = 100;
    public float maxSendTime = 10;
    bool recording = false;
//    bool shortened = false;
    float recogInterval = 1;
    float lastRecordStart = 0;
    float lastRecordLength = 0;
    float silent_thresh = 0.1f;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if(recording)
        {
            int lastPos = Microphone.GetPosition(null);
            length = (float)lastPos / samplingRate;
            if (length >= maxRecordTime)
            {
                VoiceRecognitionStart();
            }
            else if(length>= lastRecordStart+lastRecordLength + recogInterval)
            {
                if (IsSilent())
                {
                    lastRecordStart = length;
//                    print(string.Format("lastRecordStart:{0}", lastRecordStart));
                    lastRecordLength = 0;
                    SendMessage("OnSilence");
                    if (length >= maxRecordTime*0.8f)
                    {
                        VoiceRecognitionStart();
                    }
                }
                else
                {
                    lastRecordLength = length - lastRecordStart;
                    if(lastRecordLength> maxSendTime)
                    {
                        lastRecordLength = maxSendTime;
                        lastRecordStart = length - lastRecordLength;
                    }
                    SendRecordedBytes("OnVoiceRecordBytes");
                }
            }
        }
    }

    bool IsSilent()
    {
        if (length < 1)
            return false;
        var data = new float[clip.samples * clip.channels];
        clip.GetData(data, 0);
        int start = (int)((length-1) * samplingRate * clip.channels);
        int end = (int)(length * samplingRate * clip.channels);
        float max = 0;
        for (int i = start; i < end; i++)
            max = Mathf.Max(max, data[i]);

//        print(string.Format("max:{0}",max));
        return max<silent_thresh;
    }

    public void VoiceRecognitionStart()
    {
        try
        {
            Microphone.End(null);
            clip = Microphone.Start(null, false, maxRecordTime, samplingRate);
            recording = true;
            lastRecordStart = 0;
            lastRecordLength = 0;
            print("recording started...");
        }
        catch (Exception e)
        {
            print("TryStartRecording(), failed...");
            print(e);
        }
    }

    void SendRecordedBytes(string funcName)
    {
        var data = new float[clip.samples * clip.channels];
        clip.GetData(data, 0);
        int floatStart = (int)(lastRecordStart * samplingRate * clip.channels);
        int floatLen = (int)(length * samplingRate * clip.channels) - floatStart;
        var samplesShort = new short[floatLen];
        for (var index = 0; index < floatLen; index++)
            samplesShort[index] = (short)(data[floatStart+index] * short.MaxValue);

        byte[] datas = new byte[samplesShort.Length * 2];
        Buffer.BlockCopy(samplesShort, 0, datas, 0, datas.Length);

        SendMessage(funcName, datas);
    }

    public void VoiceRecognitionStop()
    {
        recording = false;
        print("recording stopped.");
        int lastPos = Microphone.GetPosition(null);
        if (Microphone.IsRecording(null))
        {
            length = (float)lastPos / samplingRate;
//            shortened = true;
        }
        else
        {
            length = maxRecordTime;
//            shortened = false;
        }

        Microphone.End(null);

    }
#endif
}
